package com.rede.didiok.file.util;

import java.io.BufferedInputStream;
import java.io.File;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;

import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.entity.ContentType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import com.rede.didiok.common.constant.conf.MessageConf;
import com.rede.didiok.common.constant.global.Constants;
import com.rede.didiok.common.dto.admin.SystemConfigDto;
import com.rede.didiok.common.utils.FileUtils;
import com.rede.didiok.common.utils.ResultUtil;

/**
 * 本地对象存储服务 Minio上传工具类
 *
 */
@Component
@Slf4j
public class MinioUtil {

    /**
     * 文件上传
     *
     * @param file
     * @return
     * @throws Exception
     */
    public String uploadFile(SystemConfigDto systemConfig, MultipartFile file) {
        String newFileName = System.currentTimeMillis() + Constants.SYMBOL_POINT + FileUtils.getFileSuffix(file.getOriginalFilename());
        return this.uploadSingleFile(systemConfig, file, newFileName);
    }

    public String uploadFile(SystemConfigDto systemConfig, File tempFile, String newFileName) {
        return this.uploadSingleFile(systemConfig, getMultipartFile(tempFile), newFileName);
    }

    private MultipartFile getMultipartFile(File file) {
        BufferedInputStream bis = null;
        MultipartFile multipartFile = null;
        try {
            bis = new BufferedInputStream(Files.newInputStream(file.toPath()));
            multipartFile = new MockMultipartFile(file.getName(), file.getName(),
                    ContentType.APPLICATION_OCTET_STREAM.toString(), bis);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return multipartFile;
    }

    /**
     * 批量文件上传
     *
     * @param list
     * @return
     * @throws Exception
     */
    public String batchUploadFile(SystemConfigDto systemConfig, List<MultipartFile> list) {
        List<String> urlList = new ArrayList<>();
        for (MultipartFile file : list) {
            //获取新文件名
            urlList.add(this.uploadFile(systemConfig, file));
        }
        return ResultUtil.successWithData(urlList);
    }

    /**
     * 删除单个文件
     *
     * @param fileName
     * @return
     */
    public String deleteFile(SystemConfigDto systemConfig, String fileName) {
        try {
            // MinioClient minioClient = new MinioClient(systemConfig.getMinioEndPoint(), systemConfig.getMinioAccessKey(), systemConfig.getMinioSecretKey());
            // MinioClient.builder()
            //         .endpoint(endpoint)
            //         .credentials(accessKey, secretKey)
            //         .build();
            MinioClient minioClient = MinioClient.builder().endpoint(systemConfig.getMinioEndPoint()).credentials(systemConfig.getMinioAccessKey(), systemConfig.getMinioSecretKey()).build();
            // Remove object.
            minioClient.removeObject(
                    RemoveObjectArgs.builder().bucket(systemConfig.getMinioBucket()).object(fileName).build());
        } catch (Exception e) {
            log.error("删除Minio中的文件失败 fileName: {}, 错误消息: {}", fileName, e.getMessage());
            return ResultUtil.errorWithData(MessageConf.DELETE_DEFAULT_ERROR);
        }
        return ResultUtil.successWithMessage(MessageConf.DELETE_SUCCESS);
    }

    /**
     * 批量删除文件
     *
     * @param fileNameList
     * @return
     */
    public String deleteBatchFile(SystemConfigDto systemConfig, List<String> fileNameList) {
        MinioClient minioClient = MinioClient.builder().endpoint(systemConfig.getMinioEndPoint()).credentials(systemConfig.getMinioAccessKey(), systemConfig.getMinioSecretKey()).build();
        try {
            for (String fileName : fileNameList) {
                minioClient.removeObject(
                        RemoveObjectArgs.builder().bucket(systemConfig.getMinioBucket()).object(fileName).build());
            }
        } catch (Exception e) {
            log.error("批量删除文件失败, 错误消息: {}", e.getMessage());
            return ResultUtil.errorWithData(MessageConf.DELETE_DEFAULT_ERROR);
        }
        return ResultUtil.successWithMessage(MessageConf.DELETE_SUCCESS);
    }

    /**
     * 上传单个文件，返回上传成功后的地址
     *
     * @param multipartFile
     * @return
     */
    private String uploadSingleFile(SystemConfigDto systemConfig, MultipartFile multipartFile,String newFileName) {
        String url = "";
        try {
            // 使用MinIO服务的URL，端口，Access key和Secret key创建一个MinioClient对象
            MinioClient minioClient = MinioClient.builder().endpoint(systemConfig.getMinioEndPoint()).credentials(systemConfig.getMinioAccessKey(), systemConfig.getMinioSecretKey()).build();
            // 重新生成一个文件名
            minioClient.putObject(
                    PutObjectArgs.builder().bucket(systemConfig.getMinioBucket()).object(newFileName).stream(
                                    multipartFile.getInputStream(), multipartFile.getSize(), -1)
                            .contentType(multipartFile.getContentType())
                            .build());

            url = Constants.SYMBOL_LEFT_OBLIQUE_LINE + systemConfig.getMinioBucket() + Constants.SYMBOL_LEFT_OBLIQUE_LINE + newFileName;
        } catch (Exception e) {
            e.getStackTrace();
            log.error("上传文件出现异常: {}", e.getMessage());
        }
        return url;
    }
}
